namespace Spotted.Storage.Queues.ViewModels
{
    using System;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    using System.Globalization;
    using System.Linq;
    using Microsoft.WindowsAzure.Samples.Phone.Storage;

    public class ListQueuesPageViewModel : INotifyPropertyChanged
    {
        private readonly ICloudQueueClient queueClient;
        private bool isLoading;
        private bool hasResults = true;
        private string prefix = string.Empty;
        private string message;

        public ListQueuesPageViewModel()
            : this(CloudStorageContext.Current.Resolver.CreateCloudQueueClient())
        {
        }

        public ListQueuesPageViewModel(ICloudQueueClient queueClient)
        {
            this.queueClient = queueClient;
            this.CloudQueues = new ObservableCollection<ICloudQueue>();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public ObservableCollection<ICloudQueue> CloudQueues { get; set; }

        public bool IsLoading
        {
            get
            {
                return this.isLoading;
            }

            set
            {
                if (this.isLoading != value)
                {
                    this.isLoading = value;
                    this.NotifyPropertyChanged("IsLoading");
                }
            }
        }

        public bool HasResults
        {
            get
            {
                return this.hasResults;
            }

            set
            {
                if (this.hasResults != value)
                {
                    this.hasResults = value;
                    this.NotifyPropertyChanged("HasResults");
                }
            }
        }

        public string Prefix
        {
            get
            {
                return this.prefix;
            }

            set
            {
                if (this.prefix != value)
                {
                    this.prefix = value;
                    this.NotifyPropertyChanged("Prefix");
                }
            }
        }

        public string Message
        {
            get
            {
                return this.message;
            }

            set
            {
                if (this.message != value)
                {
                    this.message = value;
                    this.NotifyPropertyChanged("Message");
                }
            }
        }

        public void ListQueues()
        {
            if (this.IsLoading)
                return;

            this.IsLoading = true;
            this.Message = "Listing queues...";
            try
            {
                this.queueClient.ListQueues(
                    this.Prefix,
                    result =>
                        {
                            if (result.Success)
                            {
                                this.CloudQueues.Clear();
                                foreach (var queue in result.Response)
                                {
                                    this.CloudQueues.Add(queue);
                                }

                                this.HasResults = this.CloudQueues.Count > 0;
                                this.Message = "Listing finished successfully.";
                            }
                            else
                            {
                                this.Message = string.Concat("Error: ", result.ErrorMessage);
                            }

                            this.IsLoading = false;
                        });
            }
            catch (Exception exception)
            {
                this.IsLoading = false;
                this.Message = string.Concat("Error: ", exception.Message);
            }
        }

        public void NewQueue()
        {
            this.Message = "Creating new queue...";
            this.IsLoading = true;

            try
            {
                var uniqueQueueName = string.Concat("Queue", DateTime.Now.ToString("yyyyMMddTHHmmss", CultureInfo.InvariantCulture)).ToLowerInvariant();
                var currentQueue = this.queueClient.GetQueueReference(uniqueQueueName);
                currentQueue.Create(creationResult => this.OnCreateQueue(currentQueue, creationResult));
            }
            catch (Exception exception)
            {
                this.IsLoading = false;
                this.Message = string.Concat("Error: ", exception.Message);
            }
        }

        public void DeleteQueue(ICloudQueue queue)
        {
            this.Message = "Deleting queue...";
            this.IsLoading = true;

            try
            {
                var currentQueue = this.queueClient.GetQueueReference(queue.Name);
                currentQueue.Delete(deletionResult =>
                    {
                        if (deletionResult.Success)
                        {
                            var listedQueue = this.CloudQueues.Where(q => q.Name.Equals(currentQueue.Name, StringComparison.InvariantCulture)).SingleOrDefault();
                            if (listedQueue != null)
                            {
                                this.CloudQueues.Remove(listedQueue);
                                this.Message = "Changes saved successfully.";
                            }
                        }
                        else
                        {
                            this.Message = string.Concat("Error: ", deletionResult.ErrorMessage);
                        }

                        this.IsLoading = false;
                    });
            }
            catch (Exception exception)
            {
                this.IsLoading = false;
                this.Message = string.Concat("Error: ", exception.Message);
            }
        }

        protected virtual void NotifyPropertyChanged(string propertyName)
        {
            var propertyChanged = this.PropertyChanged;
            if (propertyChanged != null)
                propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        private void OnCreateQueue(ICloudQueue currentQueue, CloudOperationResponse<bool> creationResult)
        {
            if (creationResult.Success)
            {
                this.CloudQueues.Add(currentQueue);
                this.HasResults = true;
                this.Message = "Changes saved successfully.";
            }
            else
            {
                this.Message = string.Concat("Error: ", creationResult.ErrorMessage);
            }

            this.IsLoading = false;
        }
    }
}
